#include "StdAfx.h"
#include "OrganInstrument.h"
#include "Notes.h"
#include <vector>


COrganInstrument::COrganInstrument(void)
{
	m_duration = 0.1;
	m_drawbars.resize(9,0.0);
	m_changeleslie = true;
}


COrganInstrument::~COrganInstrument(void)
{
}

void COrganInstrument::Start()
{
    m_organ.SetSampleRate(GetSampleRate());
    m_organ.Start();
    m_time = 0;

	m_organenvelope.SetSource(&m_organ);
	m_organenvelope.SetSampleRate(GetSampleRate());
    m_organenvelope.Start();
}


void COrganInstrument::SetNote(CNote *note)
{
    // Get a list of all attribute nodes and the
    // length of that list
    CComPtr<IXMLDOMNamedNodeMap> attributes;
    note->Node()->get_attributes(&attributes);
    long len;
    attributes->get_length(&len);

    // Loop over the list of attributes
    for(int i=0;  i<len;  i++)
    {
        // Get attribute i
        CComPtr<IXMLDOMNode> attrib;
        attributes->get_item(i, &attrib);

        // Get the name of the attribute
        CComBSTR name;
        attrib->get_nodeName(&name);

        CComVariant value;
        attrib->get_nodeValue(&value);

        if(name == "duration")
        {
            value.ChangeType(VT_R8);
            SetDuration(value.dblVal);
        }
        else if(name == "note")
        {
            SetFreq(NoteToFrequency(value.bstrVal));
        }
        else if(name == "attack")
        {
            value.ChangeType(VT_R8);
            m_ar.SetAttack(value.dblVal);
        }
        else if(name == "release")
        {
            value.ChangeType(VT_R8);
            m_organenvelope.SetRelease(value.dblVal);
        }
		else if(name == "decay")
        {
            value.ChangeType(VT_R8);
            m_organenvelope.SetDecay(value.dblVal);
        }
		else if(name == "amplitude")
		{
			value.ChangeType(VT_R8);
			SetAmplitude(value.dblVal);
		}
		else if(name == "VibratoFrequency")
		{
			value.ChangeType(VT_R8);
			SetVibratoFreq(value.dblVal);
		}
		else if(name == "VibratoMagnitude")
		{
			value.ChangeType(VT_R8);
			SetVibratoMag(value.dblVal);
		}
		else if(name == "LeslieFrequency")
		{
			value.ChangeType(VT_R8);
			SetLeslieFreq(value.dblVal);
			SetLeslieChanged(true);
		}
		else if(name == "LeslieEndFrequency")
		{
			value.ChangeType(VT_R8);
			SetLeslieEndFreq(value.dblVal);
		}
		else if(name == "LeslieAttackTime")
		{
			value.ChangeType(VT_R8);
			SetLeslieAttackTime(value.dblVal);
		}
		else if(name == "LeslieReleaseTime")
		{
			value.ChangeType(VT_R8);
			SetLeslieReleaseTime(value.dblVal);
		}
		else if(name == "LeslieRadius")
		{
			value.ChangeType(VT_R8);
			SetLeslieRadius(value.dblVal);
		}
    }

}
bool COrganInstrument::Generate()
{
	m_organ.Generate();
    bool valid = m_organenvelope.Generate();

    m_frame[0] = m_organenvelope.Frame(0);
    m_frame[1] = m_organenvelope.Frame(1);

    m_time += GetSamplePeriod();
    return valid;
}
void COrganInstrument::SetLeslieAttackTime(double LeslieAT)
{
	if(m_changeleslie) 
	{
		m_organ.SetLeslieAttackTime(LeslieAT);
		m_changeleslie = false;
	}
}	
void COrganInstrument::SetDrawbars(int drawbarNum)
{
	int value=0;
	double example=0.0;
	int simp1,simp2;
	double simp3;
	for(int i=0;i<9;i++)
	{
		simp1 = pow((double)10,(9-i));
		simp2 = pow((double)10,(8-i));
		value = drawbarNum%simp1;
		value = value/simp2;
		if(value!=0)
		{
			simp3 = pow((double)10,(((8-(double)value)*-3)/20));
			m_drawbars[i]=simp3;
		}
	}
}
